
/*
{
chunk = [4b]data size
        [4b]chunk type
        [xx]data
        [4b]crc del data+chunk type
}

[ID]
89 50 4E 47 0D 0A 1A 0A //137 80 78 71 13 10 26 10

[chunk IHDR]
data size 00 00 00 0D //13
chunk type 49 48 44 52 (IHDR)
data
4b, 00 00 00 F0 //240
4b, 00 00 01 40 //320
1b, 08 //256
1b, 03 //rgb,color
1b, 00 //compression: inflate/deflate
1b, 00 //filter: default, method 0
1b, 00 //interlace: no
crc 00 00 00 00

[chunk PLTE]
data size 00 00 03 00 //768
chunk type 50 4C 54 45 (PLTE)
data
FF FF FF (R,G,B)
...
crc 00 00 00 00


[chunk IDAT]
data size 00 variable //76800+256 ceros del type -> deflate
chunk type 49 44 41 54 (IDAT)
data
0 + scanline0 //0-> no filter for method #0
0 + scanline1
0 + scanline2
... -> se hace un deflate y se pega aqui
crc 00 00 00 00


[chunk IEND]
data size 00 00 00 00
chunk type 49 45 4E 44 (IEND)
data no
crc 00 00 00 00
*/

#define QuickCpy(a) gm_memcpy(&dst[total],a,sizeof(a)); total+=sizeof(a);
#define WriteCRC() dst[total++]=(CRC>>24)&0xFF;  dst[total++]=(CRC>>16)&0xFF;   dst[total++]=(CRC>>8)&0xFF;   dst[total++]=CRC&0xFF; 
#define QuickCRC(b,c) { int l; for(l=b;l<c;l++) GetCRC(dst[l]); }

int SavePNG8(unsigned char *src,unsigned char *dst,unsigned char pal[768])
{
 unsigned char ID[]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a};
 unsigned char IHDR[]={0x00,0x00,0x00,0x0D, 0x49,0x48,0x44,0x52, 0,0,1,0x40, 0,0,0,0xf0, 8,3,0,0,0 };
 unsigned char PLTE[]={0x00,0x00,0x03,0x00, 0x50,0x4c,0x54,0x45};
 unsigned char IDAT[]={0x00,0x00,0x00,0x00, 0x49,0x44,0x41,0x54};
 unsigned char tEXt[]={0x00,0x00,0x00,0x00, 't','E','X','t'};
 unsigned char IEND[]={0x00,0x00,0x00,0x00, 0x49,0x45,0x4E,0x44, 0xae,0x42,0x60,0x82};
 unsigned char *gfx; //320*240+240 bytes of filter type
 int total=0,CRCbackup=CRC;

 gfx=(unsigned char *)gm_malloc(320*240+240);

 QuickCpy(ID);

 QuickCpy(IHDR);
 CRC=0;QuickCRC(total-(sizeof(IHDR)-4),total);
 WriteCRC();

 QuickCpy(PLTE);
 gm_memcpy(&dst[total],pal,768); total+=768;
 CRC=0;QuickCRC(total-768-(sizeof(PLTE)-4),total);
 WriteCRC();
 
 {
  int x,y; uLongf destLen=((320*240+240)*1.1)+12;

  for(y=0;y<240;y++) for(gfx[y*(320+1)]=0/*filter*/,x=0;x<320;x++) gfx[(x+1)+y*(320+1)]=src[(240-y)+x*240];

  QuickCpy(IDAT);

  if(compress((Bytef *)&dst[total], &destLen, (const Bytef *)&gfx[0], 320*240+240)!=Z_OK) return 0;

  dst[total-8+0]=(destLen>>24)&0xff;
  dst[total-8+1]=(destLen>>16)&0xff;
  dst[total-8+2]=(destLen>>8)&0xff;
  dst[total-8+3]=(destLen)&0xff;

  total+=destLen;

  CRC=0;QuickCRC(total-destLen-(sizeof(IDAT)-4),total);
  WriteCRC();
 }

 {
 char t[]="Title\0Generated by fNES32!",s=sizeof(t)-1;

 QuickCpy(tEXt);

 gm_memcpy(&dst[total],t,s);

 dst[total-8+0]=(s>>24)&0xff;
 dst[total-8+1]=(s>>16)&0xff;
 dst[total-8+2]=(s>>8)&0xff;
 dst[total-8+3]=(s)&0xff;

 total+=s;

 CRC=0;QuickCRC(total-s-(sizeof(tEXt)-4),total);
 WriteCRC();
 }


 QuickCpy(IEND);

 gm_free(gfx);

 CRC=CRCbackup;

 return total;
}

//http://www.daubnet.com/formats/BMP.html
int SaveBMP(unsigned char *src,unsigned char *dst,unsigned char *pal)
{                                 //size                                    //offset pa las datas 14+40+256*4
 unsigned char HEADER[]={'B','M', 0x036,0x30,0x1,0x00, 0x00,0x00,0x00,0x00, 0x36,0x04,0x00,0x00};        
 unsigned char INFOHD[]={40,0,0,0, 0x40,1,0,0, 0xf0,0,0,0, 1,0, 8,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
 int total=0,i,x,y;

 QuickCpy(HEADER);
 QuickCpy(INFOHD);
                                                                                             
 for(i=0;i<256;i++) { unsigned char r,g,b; r=*pal++; g=*pal++; b=*pal++; dst[total++]=b;dst[total++]=g;dst[total++]=r;dst[total++]=0;  }

 for(y=240-1;y>=0;y--) for(x=0;x<320;x++) dst[total++]=src[(240-y)+x*240];

 return total;
}

//http://astronomy.swin.edu.au/pbourke/dataformats/tga/
int SaveTGA(unsigned char *src,unsigned char *dst,unsigned char pal[768])
{
 unsigned char SIGN[]="Generated by fMSX32!";
 unsigned char HEADER[]={sizeof(SIGN), 1,1, 0,0,0xFF,0,24, 0,0,0,0,0x40,0x1,0xF0,0,8,0 };
 int total=0,x,y;

 QuickCpy(HEADER);
 QuickCpy(SIGN);
 gm_memcpy(&dst[total],pal,768); total+=768;

 for(y=0;y<240;y++) for(x=0;x<320;x++) dst[total++]=src[(240-y)+x*240];

 return total;
}
